package utils

import (
	consts2 "MoSkeleton/config/consts"
	"MoSkeleton/framework"
	"MoSkeleton/framework/core/consts"
	system2 "MoSkeleton/web/pogos/respose/system"
	"context"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/redis/go-redis/v9"
	"time"
)

func SetRedisOnlineUser(userId uint64, onlineUser *system2.OnlineUserResp, expiresAt int64) error {
	key := fmt.Sprintf("%s%d", consts2.RedisKey_Online_User, userId)
	bytes, err := json.Marshal(onlineUser)
	if err != nil {
		return err
	}
	var cmdStatus *redis.StatusCmd
	if expiresAt == 0 {
		cmdStatus = framework.MoRedis.Set(context.TODO(), key, bytes, -1)
	} else {
		cmdStatus = framework.MoRedis.SetEx(context.TODO(), key, bytes, time.Duration(expiresAt-time.Now().Unix())*time.Second)
	}
	if cmdStatus.Err() != nil {
		return cmdStatus.Err()
	}
	return nil
}

func GetRedisOnlineUser(userId uint64) (*system2.OnlineUserResp, error) {
	key := fmt.Sprintf("%s%d", consts2.RedisKey_Online_User, userId)
	strCmd := framework.MoRedis.Get(context.Background(), key)
	if err := strCmd.Err(); err != nil {
		return nil, err
	}
	onlineUser := system2.NewOnlineUserResp()
	if strCmd.Val() != "" {
		err := json.Unmarshal([]byte(strCmd.Val()), onlineUser)
		if err != nil {
			return nil, err
		}
	}
	return onlineUser, nil
}

func GetOnlineUserFromGin(c *gin.Context) *system2.OnlineUserResp {
	onlineUserAny, exists := c.Get(consts.GinContext_OnlineUser_Key)
	if !exists {
		return nil
	}
	onlineUser := onlineUserAny.(*system2.OnlineUserResp)
	return onlineUser
}

func SetOnlineUserToGin(c *gin.Context, onlineUser *system2.OnlineUserResp) {
	c.Set(consts.GinContext_OnlineUser_Key, onlineUser)
}

/*
先从gin.context尝试获取，如果没有，从redis获取，并设置到gin.context
*/
func GetSetOnlineUser(c *gin.Context, userId uint64) *system2.OnlineUserResp {
	onlineUser := GetOnlineUserFromGin(c)
	if onlineUser != nil {
		return onlineUser
	}
	onlineUser, err := GetRedisOnlineUser(userId)
	if err != nil {
		return nil
	}
	SetOnlineUserToGin(c, onlineUser)
	return onlineUser
}
